#!/usr/bin/env python3
"""
Console-based System Update Service Main Entry Point

This replaces BLE-based update communication with console logging.
Use this for system updates without BLE dependency.
"""

import asyncio
import logging
import signal
import sys
import json
from pathlib import Path
from datetime import datetime

# Add project root to path
sys.path.insert(0, str(Path(__file__).parent))

from src.services.console_update_service import ConsoleUpdateService


class ConsoleUpdateManager:
    """Main manager for console-based system updates."""
    
    def __init__(self):
        self.update_service = None
        self.running = False
        self.shutdown_event = asyncio.Event()
        
        # Setup logging
        self.setup_logging()
        
    def setup_logging(self):
        """Setup comprehensive logging for the service."""
        logging.basicConfig(
            level=logging.INFO,
            format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
            handlers=[
                logging.FileHandler('system_update.log'),
                logging.StreamHandler(sys.stdout)
            ]
        )
        
        # Set specific loggers
        logging.getLogger('src.services').setLevel(logging.DEBUG)
        logging.getLogger('src.ble').setLevel(logging.WARNING)  # Reduce BLE noise
        
        logger = logging.getLogger(__name__)
        logger.info("Console Update Service logging initialized")
    
    def setup_signal_handlers(self):
        """Setup signal handlers for graceful shutdown."""
        def signal_handler(signum, frame):
            logger = logging.getLogger(__name__)
            logger.info(f"Received signal {signum}, shutting down gracefully...")
            self.shutdown_event.set()
        
        signal.signal(signal.SIGINT, signal_handler)
        signal.signal(signal.SIGTERM, signal_handler)
    
    async def start_service(self):
        """Start the console update service."""
        logger = logging.getLogger(__name__)
        
        try:
            # Initialize the console update service
            logger.info("Initializing Console Update Service...")
            self.update_service = ConsoleUpdateService()
            self.update_service.start_service()
            
            self.running = True
            logger.info("Console Update Service started successfully")
            
            # Display service information
            self.display_service_info()
            
            # Main service loop
            await self.service_loop()
            
        except Exception as e:
            logger.error(f"Failed to start Console Update Service: {e}")
            raise
    
    def display_service_info(self):
        """Display service startup information."""
        print("\n" + "="*80)
        print("CLOUD PRINTER - CONSOLE UPDATE SERVICE")
        print("="*80)
        print(f"Started at: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
        print("BLE Communication: DISABLED")
        print("Logging Mode: CONSOLE + FILE")
        print("Log File: system_update.log")
        print("="*80)
        print("\nAvailable Commands:")
        print("  check        - Check for system updates")
        print("  status       - Get current update status")
        print("  version      - Show version information")
        print("  health       - Perform health check")
        print("  help         - Show this help message")
        print("  quit         - Shutdown service")
        print("="*80)
        print("\nService is ready. Type 'help' for commands.\n")
    
    async def service_loop(self):
        """Main service loop for handling console commands."""
        logger = logging.getLogger(__name__)
        
        try:
            # Start background tasks
            tasks = [
                asyncio.create_task(self.wait_for_shutdown()),
                asyncio.create_task(self.handle_console_input()),
                asyncio.create_task(self.periodic_health_check())
            ]
            
            # Wait for shutdown signal
            done, pending = await asyncio.wait(tasks, return_when=asyncio.FIRST_COMPLETED)
            
            # Cancel remaining tasks
            for task in pending:
                task.cancel()
                try:
                    await task
                except asyncio.CancelledError:
                    pass
                    
        except Exception as e:
            logger.error(f"Service loop error: {e}")
        finally:
            await self.shutdown()
    
    async def wait_for_shutdown(self):
        """Wait for shutdown signal."""
        await self.shutdown_event.wait()
    
    async def handle_console_input(self):
        """Handle console input commands."""
        logger = logging.getLogger(__name__)
        
        while self.running:
            try:
                # Use asyncio to handle input without blocking
                await asyncio.sleep(0.1)  # Small delay to prevent CPU spinning
                
                # Check for available input (simplified for demo)
                # In production, you might want to use aioconsole or similar
                continue
                
            except Exception as e:
                logger.error(f"Console input handler error: {e}")
                break
    
    async def handle_command(self, command: str, params: dict = None):
        """Handle update commands."""
        logger = logging.getLogger(__name__)
        
        if not self.update_service:
            print("ERROR: Update service not initialized")
            return
        
        try:
            if command.lower() == "check":
                print("\n[COMMAND] Checking for updates...")
                result = await self.update_service.handle_update_command("CHECK", params or {})
                print(f"[RESULT] {json.dumps(result, indent=2)}")
            
            elif command.lower() == "status":
                print("\n[COMMAND] Getting update status...")
                status = self.update_service.get_current_status()
                print(f"[STATUS] {json.dumps(status, indent=2)}")
            
            elif command.lower() == "version":
                print("\n[COMMAND] Getting version information...")
                version_info = await self.update_service.get_version_info()
                print(f"[VERSION] {json.dumps(version_info, indent=2)}")
            
            elif command.lower() == "health":
                print("\n[COMMAND] Performing health check...")
                result = await self.update_service.handle_update_command("HEALTH_CHECK")
                print(f"[HEALTH] {json.dumps(result, indent=2)}")
            
            elif command.lower() == "help":
                self.show_help()
            
            elif command.lower() in ["quit", "exit"]:
                print("\n[COMMAND] Shutting down service...")
                self.shutdown_event.set()
            
            else:
                print(f"\n[ERROR] Unknown command: {command}")
                print("Type 'help' for available commands.")
                
        except Exception as e:
            logger.error(f"Command handler error for '{command}': {e}")
            print(f"[ERROR] Failed to execute command '{command}': {e}")
    
    def show_help(self):
        """Show help information."""
        print("\n" + "="*50)
        print("CONSOLE UPDATE SERVICE - COMMAND HELP")
        print("="*50)
        print("Commands:")
        print("  check        - Check for available system updates")
        print("  status       - Display current update status and progress")
        print("  version      - Show detailed version information")
        print("  health       - Perform comprehensive system health check")
        print("  help         - Show this help message")
        print("  quit/exit    - Gracefully shutdown the service")
        print("\nExamples:")
        print("  check        # Check for updates")
        print("  status       # Show current status")
        print("  health       # Run health diagnostics")
        print("="*50 + "\n")
    
    async def periodic_health_check(self):
        """Perform periodic health checks."""
        logger = logging.getLogger(__name__)
        
        while self.running:
            try:
                await asyncio.sleep(300)  # Check every 5 minutes
                
                if not self.running:
                    break
                
                logger.info("Performing periodic health check...")
                await self.update_service.handle_update_command("HEALTH_CHECK")
                
            except Exception as e:
                logger.error(f"Periodic health check error: {e}")
            
    async def shutdown(self):
        """Gracefully shutdown the service."""
        logger = logging.getLogger(__name__)
        logger.info("Shutting down Console Update Service...")
        
        self.running = False
        
        if self.update_service:
            print("\n[SHUTDOWN] Console Update Service stopped")
            logger.info("Console Update Service shutdown completed")
    
    # Simple command interface for testing
    def run_command(self, command: str, params: dict = None):
        """Run a single command and return result (for testing)."""
        return asyncio.run(self.handle_command(command, params))


# Interactive command mode for manual testing
async def interactive_mode():
    """Interactive command mode."""
    manager = ConsoleUpdateManager()
    
    try:
        print("Starting Console Update Service in interactive mode...")
        print("Type commands or 'help' for assistance, 'quit' to exit.\n")
        
        # Initialize service
        manager.update_service = ConsoleUpdateService()
        manager.update_service.start_service()
        manager.running = True
        
        while True:
            try:
                # Get user input
                user_input = input("\nupdate-service> ").strip()
                
                if not user_input:
                    continue
                
                if user_input.lower() in ['quit', 'exit']:
                    break
                
                # Parse command
                parts = user_input.split()
                command = parts[0]
                params = {}
                
                # Handle command
                await manager.handle_command(command, params)
                
            except KeyboardInterrupt:
                print("\n\nReceived interrupt signal. Shutting down...")
                break
            except EOFError:
                print("\nReceived EOF. Shutting down...")
                break
            except Exception as e:
                print(f"Error processing command: {e}")
    
    finally:
        await manager.shutdown()


async def main():
    """Main entry point."""
    if len(sys.argv) > 1 and sys.argv[1] == '--interactive':
        await interactive_mode()
    else:
        # Service mode
        manager = ConsoleUpdateManager()
        manager.setup_signal_handlers()
        await manager.start_service()


if __name__ == "__main__":
    try:
        asyncio.run(main())
    except KeyboardInterrupt:
        print("\nService interrupted by user")
    except Exception as e:
        print(f"Service failed: {e}")
        sys.exit(1)